//
//  BCSDate.swift
//  BCFoundation
//
//  Created by Basic on 2019/6/27.
//  date category

import Foundation


/// 星期map
public let BCWeekMap = [1: BCLOC("日"),
               2: BCLOC("一"),
               3: BCLOC("二"),
               4: BCLOC("三"),
               5: BCLOC("四"),
               6: BCLOC("五"),
               7: BCLOC("六")]


/// 星期元组集合
/// - Parameter start: 开始的日期 默认周日为第一天
/// - Returns: description
public func BCWeekTuples(_ start: Int = 1) -> [(value: Int, text: String)] {
    var tupleArr: [(value: Int, text: String)] = []
    // 最小值为1
    var startIndex = max(1, start)
    for _ in 0 ... 6 {
        if startIndex > 7 {
            startIndex = 1
        }
        guard let weekValue = BCWeekMap[startIndex] else {
            continue
        }
        let tuple = (startIndex, weekValue)
        tupleArr.append(tuple)
        startIndex += 1
    }
    return tupleArr
}

public extension Date {
    
    //MARK: -  格式化日期
    private static var bc_format:DateFormatter?
    
    
    /// 格式化日期
    ///
    /// - Parameter format: 自定义格式 yyyy-MM-dd HH:mm:ss
    /// - Returns: 日期字符串
    func bc_formatDateWithFormat(_ format:String) -> String {
        if Date.bc_format == nil {
            Date.bc_format = DateFormatter()
        }
        Date.bc_format?.dateFormat = format
        return Date.bc_format?.string(from: self) ?? ""
    }
    
    /// 格式化 日期
    ///
    /// - Returns: 今天显示 “今天 HH:mm:ss”，其他日期显示 "yyyy-MM-dd HH:mm:ss"
    func bc_formatFullDate() -> String {
        if Date.bc_format == nil {
            Date.bc_format = DateFormatter()
        }
        var result:String = ""
        if self.bc_isToday() {
            //今天
            Date.bc_format?.dateFormat = "HH:mm:ss";
            result = Date.bc_format?.string(from: self) ?? ""
            result = String(format: "%@ %@", BCLOC("今天"), result)
        } else {
            //其他
            Date.bc_format?.dateFormat = "yyyy-MM-dd HH:mm:ss"
            result = Date.bc_format?.string(from: self) ?? ""
        }
        return result
    }

    /// 根据 格式、时间戳格式化日期
    ///
    /// - Parameters:
    ///   - timeStamp: 时间戳 毫秒
    ///   - style: 日期格式
    static func bc_formatDateStr(_ timeStamp: TimeInterval, _ style:String) -> String {
        if Date.bc_format == nil {
            Date.bc_format = DateFormatter()
        }
        let timeStampNew = timeStamp / 1000.0
        Date.bc_format?.dateFormat = style
        let receiveDate = Date(timeIntervalSince1970: timeStampNew)
        return Date.bc_format?.string(from: receiveDate) ?? ""
    }

    //MARK: - helper
    
    /// 当前 date 是否是今天
    ///
    /// - Returns: true or false
    func bc_isToday() -> Bool {
        let cal = Calendar.current
        let components = cal.dateComponents([.year, .month, .day], from: Date())
        let today = cal.date(from: components)
        let otherComponents = cal.dateComponents([.year, .month, .day], from: self)
        let otherDate = cal.date(from: otherComponents)
        return today == otherDate
    }
    /// 毫秒时间戳转成 分钟' 秒,如：23' 42
    ///
    /// - Parameters:
    ///   - time: 时间戳 毫秒
    ///   - splitStr: 分割字符串，默认 '
    static func bc_toMinuteSecond(_ time:Int, _ splitStr:String="' ") -> String {
        let second:Int = time/1000
        if second < 60 {
            return "\(second)"
        }
        let minute = second/60%60
        let secondStr = second%60
        return String(format: "%d%@%02d", minute, splitStr, secondStr)
    }
    /// 毫秒时间戳转成 秒" 毫秒,如：23" 42
    ///
    /// - Parameters:
    ///   - time: 时间戳 毫秒
    ///   - splitStr: 分割字符串，默认 "
    ///   - round: 毫秒是否需要四舍五入，默认 false
    static func bc_toMillisecond(_ time:Int, _ splitStr:String="\" ", _ milliSecondDigit:Int=2, _ round:Bool = false) -> String {
        let fsecond:Double = Double(time)/1000.0
        let second = Int(fsecond)%60
        //毫秒位数
        var milliSecondDigitTmp:Int = milliSecondDigit
        if milliSecondDigitTmp>3 {
            milliSecondDigitTmp = 3
        }
        else if milliSecondDigitTmp < 1 {
            milliSecondDigitTmp = 1
        }
        var millSecondDB:Double = Double(time%1000)/(pow(10.0, Double(3-milliSecondDigit)))
        if round {
            millSecondDB = millSecondDB.rounded()
        }
        let millisecond = Int(millSecondDB)
        if milliSecondDigitTmp > 1 {
            return String(format: "%d%@%0\(milliSecondDigit)d", second, splitStr, millisecond)
        }
        else {
            return String(format: "%d%@%d", second, splitStr, millisecond)
        }
    }
    /// 毫秒时间戳转成 分' 秒" 毫秒,如：1' 23" 42
    ///
    /// - Parameters:
    ///   - time: 时间戳 毫秒
    ///   - minSplitStr: 分割字符串，默认 '
    ///   - secondSplitStr: 分割字符串，默认 "
    ///   - showFull: 是否全部显示，默认no，分钟<0不显示分钟
    ///   - round: 是否四舍五入，默认no，不四射五入
    static func bc_toMinuteMillisecond(_ time:Int, _ minSplitStr:String="\' ", _ secondSplitStr:String="\" ", showFull:Bool=false, round:Bool=false) -> String {
        let second:Int = time/1000
        let minute = second/60%60
        let secondStr = second%60
        let millisecond = (round) ? Int((Float(time%1000)/10.0).rounded()) : Int((Float(time%1000)/10.0))
        if !showFull, minute <= 0 {
            return String(format: "%d%@%02d", secondStr, secondSplitStr, millisecond)
        }
        else {
            return String(format: "%02d%@%02d%@%02d", minute, minSplitStr, secondStr, secondSplitStr, millisecond)
        }
    }
    
    //MARK: - string to date
    static func bc_toDate(_ dateString:String, _ style:String="yyyy-MM-dd") -> Date? {
        if Date.bc_format == nil {
            Date.bc_format = DateFormatter()
        }
        Date.bc_format?.dateFormat = style
        let date = Date.bc_format?.date(from: dateString)
        return date
    }
    
    /// 根据毫秒时间戳，计算年龄，x岁x月x日
    ///
    /// - Parameters:
    ///   - timeStamp: 毫秒时间戳
    ///   - year: 返回几岁
    ///   - month: 返回几个月
    ///   - day: 返回几天
    static func bc_toOld(_ timeStamp:TimeInterval, _ year: inout Int, _ month: inout Int, _ day: inout Int) {
        let cal = Calendar.current
        let otherDate = Date(timeIntervalSince1970: (timeStamp / 1000.0))
        let otherComponents = cal.dateComponents([.year, .month, .day], from: otherDate)
        let nowComponents = cal.dateComponents([.year, .month, .day], from: Date())
        year = (nowComponents.year ?? 0) - (otherComponents.year ?? 0)
        month = (nowComponents.month ?? 0) - (otherComponents.month ?? 0)
        day = (nowComponents.day ?? 0) - (otherComponents.day ?? 0)
    }
    
}
